XML示例


    /*
     * Author: shenjun
     */
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEditor;
    using System.Xml;
    public class XML_Operation : MonoBehaviour
    {
        private static XML_Operation instance;
        public static XML_Operation Instance { get { return instance; } }
        string fileName = "Items.xml";
        public string FilePath { get { return Application.streamingAssetsPath + "/" + fileName; } }
        public List<PackageItem> equips = new List<PackageItem>();
        public List<PackageItem> items = new List<PackageItem>();
        #region ContextMenuItem用法
        [ContextMenuItem("ResetXML", "ResetXML")]   // 给该字符串字段添加一个单独的右键菜单 并设置该菜单功能所调用的方法
        [Multiline(4)]   // 使字符串在检视面板显示成几行
        public string SS = "";
        void ResetXML()
        {
            SS = "";
        }
        #endregion
        #region Debug
        [ContextMenuItem("Reset", "ResetEquipsLoaded")]
        public List<PackageItem> equipsLoaded = new List<PackageItem>();
        [ContextMenuItem("Reset", "ResetItemsLoaded")]
        public List<PackageItem> itemsLoaded = new List<PackageItem>();
        void ResetEquipsLoaded()
        {
            equipsLoaded.Clear();
        }
        void ResetItemsLoaded()
        {
            itemsLoaded.Clear();
        }
        void AppendTest()
        {
            // 1. 使用绝对路径的XPath
            //        bool flag = AppendXML("/道具列表/装备", new PackageItem(){ id = "4", name = "铁剑", price = 500 });
            // 2. 开头是两个斜线表示文件中所有符合模式的元素都会被选出来,即使处于树中不同的层级也会被选出来。
            //        bool flag = AppendXML("//装备", new PackageItem(){ id = "4", name = "铁剑", price = 500 });
            // 3. 通配符
            //        bool flag = AppendXML("/*/装备", new PackageItem(){ id = "4", name = "铁剑", price = 500 });
            // 4. 使用方括号可以选择分支 下标从1开始 选择第一个节点
            //        bool flag = AppendXML("/道具列表/装备[1]", new PackageItem(){ id = "4", name = "铁剑", price = 500 });
            // 5. 选择最后一个节点
            //        bool flag = AppendXML("/道具列表/装备[last()]", new PackageItem(){ id = "4", name = "铁剑", price = 500 });
            // 6. 选择所有带有 倚天剑 元素并满足一定层次结构的装备节点
            //        bool flag = AppendXML("/道具列表/装备[倚天剑]", new PackageItem(){ id = "4", name = "铁剑", price = 500 });
            // 7. 选取 价格=1000的节点
            //        bool flag = AppendXML("/道具列表/装备/青铜剑[价格=1000]", new PackageItem(){ id = "4", name = "铁剑", price = 500 });
            // 8. 选取 符合一定层次结构的 装备和道具 节点
            //        bool flag = AppendXML("/道具列表/装备 | /道具列表/道具", new PackageItem(){ id = "4", name = "铁剑", price = 500 });
            // 9. 除了选择元素之外,也可以选择属性 属性都是以 @开头 这里表示选取所有id属性
            //        bool flag = AppendXML("//@id", new PackageItem(){ id = "4", name = "铁剑", price = 500 });
            // 10. 选取所有道具节点下 具有id属性的节点
            //        bool flag = AppendXML("//道具/*[@id]", new PackageItem(){ id = "4", name = "铁剑", price = 500 });
            // 11. 选取所有道具节点下 具有id属性 并且id属性等于12的节点
            //        bool flag = AppendXML("//道具/*[@id=12]", new PackageItem(){ id = "4", name = "铁剑", price = 500 });
            // 12. 通过节点名查找
            bool flag = AppendXML("大还丹", new PackageItem(){ id = "4", name = "铁剑", price = 500 }, true);
            if (!flag)
                Debug.Log("插入失败");
        }
        void RemoveTest()
        {
            //        bool flag = RemoveXML("//*[@id=12]");
            //        bool flag = RemoveXML("/道具列表/装备/倚天剑");
            //        bool flag = RemoveXML("/道具列表/装备/*[价格=1000]");
            bool flag = RemoveXML("屠龙刀", true);
            if (!flag)
                Debug.Log("删除失败");
        }
        void ModifyTest()
        {
            bool flag = ModifyXML("//*[@id=12]/价格", "2000");
            if (!flag)
            {
                Debug.Log("修改失败");
            }
        }
        void GetXMLNodeTest()
        {
            List<PackageItem> items;
    //        items = GetXMLNode("//*[@id=11]");
            items = GetXMLNode("青铜剑", true);
            foreach (var item in items)
            {
                Debug.Log("Name :" + item.name);
                Debug.Log("Id : " + item.id);
                Debug.Log("Price : " + item.price);
            }
        }
        #endregion
        void Awake()
        {
            instance = this;
        }
        void Start()
        {
    //        AppendTest();
    //        RemoveTest();
    //        ModifyTest();
    //        GetXMLNodeTest();
        }
        public List<PackageItem> GetXMLNode(string xpath, bool byTag = false)
        {
            if (!System.IO.File.Exists(FilePath))
                return null;
            List<PackageItem> nodesList = new List<PackageItem>();
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load(FilePath);
            XmlNodeList nodes;
            if (byTag)
            {
                nodes = xmlDoc.GetElementsByTagName(xpath);
            }
            else
            {
                nodes = xmlDoc.SelectNodes(xpath);
            }
            foreach (XmlElement n in nodes)
            {
                PackageItem item = new PackageItem();
                item.name = n.Name;
                if (n.HasAttribute("id"))
                {
                    item.id = n.GetAttribute("id");
                }
                if (n.HasChildNodes)
                {
                    int.TryParse(n.FirstChild.InnerText, out item.price);
                }
                nodesList.Add(item);
            }
            return nodesList;
        }
        [ContextMenu("生成道具XML文件")]
        void CreateXML()
        {
            if (System.IO.File.Exists(FilePath))
            {
                System.IO.File.Delete(FilePath);
            }
            XmlDocument xmlDoc = new XmlDocument();
            XmlDeclaration xmlDec = xmlDoc.CreateXmlDeclaration("1.0", "UTF-8", null);
            xmlDoc.AppendChild(xmlDec);
            // 只允许有一个根节点
            XmlElement root = xmlDoc.CreateElement("道具列表");
            if (equips.Count > 0)
            {
                XmlElement xmlEquip = xmlDoc.CreateElement("装备");
                foreach (var item in equips)
                {
                    XmlElement name = xmlDoc.CreateElement(item.name);
                    name.SetAttribute("id", item.id);
                    XmlElement price = xmlDoc.CreateElement("价格");
                    price.InnerText = item.price.ToString();
                    xmlEquip.AppendChild(name);
                    name.AppendChild(price);
                }
                root.AppendChild(xmlEquip);
            }
            if (items.Count > 0)
            {
                XmlElement xmlItem = xmlDoc.CreateElement("道具");
                foreach (var item in items)
                {
                    XmlElement name = xmlDoc.CreateElement(item.name);
                    name.SetAttribute("id", item.id);
                    XmlElement price = xmlDoc.CreateElement("价格");
                    price.InnerText = item.price.ToString();
                    xmlItem.AppendChild(name);
                    name.AppendChild(price);
                }
                root.AppendChild(xmlItem);
            }
            xmlDoc.AppendChild(root);
            xmlDoc.Save(FilePath);
            #if UNITY_EDITOR
            AssetDatabase.Refresh();
            #endif
        }
        [ContextMenu("载入XML文件")]
        void LoadXML()
        {
            equipsLoaded.Clear();
            itemsLoaded.Clear();
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load(FilePath);
    //        XmlElement root = xmlDoc.DocumentElement;
    //        Debug.Log("Root : " + root.Name);
            // XPath的开头是一个斜线代表这是绝对路径,可以选出所有路径符合这个模式的元素。
            XmlNode node = xmlDoc.SelectSingleNode("/道具列表/装备");
            XmlNodeList pNodeList = node.ChildNodes;
            foreach (var item in pNodeList)
            {
                XmlElement element = item as XmlElement;
                if (element != null)
                {
                    PackageItem equip = new PackageItem();
                    equip.name = element.Name;
                    equip.id = element.GetAttribute("id");
                    equip.price = int.Parse(element.InnerText);
                    equipsLoaded.Add(equip);
                }
            }
            node = xmlDoc.SelectSingleNode("/道具列表/道具");
            pNodeList = node.ChildNodes;
            foreach (var item in pNodeList)
            {
                XmlElement element = item as XmlElement;
                if (element != null)
                {
                    PackageItem equip = new PackageItem();
                    equip.name = element.Name;
                    equip.id = element.GetAttribute("id");
                    equip.price = int.Parse(element.InnerText);
                    itemsLoaded.Add(equip);
                }
            }
        }
        public bool AppendXML(string xpath, PackageItem item, bool byTag = false)
        {
            if (!System.IO.File.Exists(FilePath))
                return false;
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load(FilePath);
            XmlNodeList nodes;
            if (byTag)
            {
                nodes = xmlDoc.GetElementsByTagName(xpath);
            }
            else
            {
                nodes = xmlDoc.SelectNodes(xpath);
            }
            if (nodes == null || nodes.Count == 0)
                return false;
            // 测试第9点 获取所有满足条件的属性
    //        foreach (XmlAttribute n in nodes) 
    //        {
    //            Debug.Log(n.Value);
    //            Debug.Log(n.OwnerElement.Name);
    //        }
            foreach (XmlElement node in nodes)
            {
                XmlElement name = xmlDoc.CreateElement(item.name);
                name.SetAttribute("id", item.id);
                XmlElement price = xmlDoc.CreateElement("价格");
                price.InnerText = item.price.ToString();
                name.AppendChild(price);
                node.AppendChild(name);
            }
            xmlDoc.Save(FilePath);  // 保存
            return true;
        }
        public bool RemoveXML(string xpath, bool byTag = false)
        {
            if (!System.IO.File.Exists(FilePath))
                return false;
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load(FilePath);
            XmlNodeList nodes;
            if (byTag)
            {
                nodes = xmlDoc.GetElementsByTagName(xpath);
            }
            else
            {
                nodes = xmlDoc.SelectNodes(xpath);
            }
            if (nodes == null || nodes.Count == 0)
                return false;
            for (int i = 0; i < nodes.Count; i++)
            {
                Debug.Log("删除节点:" + nodes[i].Name);
                nodes[i].ParentNode.RemoveChild(nodes[i]);
            }
            xmlDoc.Save(FilePath);
            return true;
        }
        public bool ModifyXML(string xpath, string value)
        {
            if (!System.IO.File.Exists(FilePath))
                return false;
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load(FilePath);
            XmlNodeList nodes = xmlDoc.SelectNodes(xpath);
            if (nodes == null || nodes.Count == 0)
                return false;
            foreach (XmlElement n in nodes)
            {
                n.InnerText = value;
            }
            xmlDoc.Save(FilePath);
            return true;
        }
    }
    [System.Serializable]
    public struct PackageItem
    {
        public string id;
        public string name;
        public int price;
    }